#ifndef READ_FILE_LINES_H
#define READ_FILE_LINES_H

#include <string>
#include <istream>
#include <iostream>
#include <fstream>
#include <stdexcept>
#include "get_filename.h"
#include "ultoa.h"
#include "open_fstream.h"
#include "progress_indicator.h"
//________________________________________________________________________________________

//		read_line_data_from_stream


//			takes CALLBACK function/object. E.g.
// 
//			struct xxx{
// 					void operator()(istream& is, unsigned cnt_line);
// 			}
// 			
//          where cnt_line is 1 denominated
//

//________________________________________________________________________________________
template <typename CALLBACK> 
void read_file_lines(	CALLBACK&			callback, 
						const std::string&	file_path,
						std::ostream&		VERBOSE,
						char				line_separator = '\n')
{
	std::ifstream ifs;
	std::istream::pos_type file_size = 0;
	std::string file_name = "STDIN";
	bool use_stdin = !file_path.length() || file_path == "STDIN" || file_path == "-";
	if (!use_stdin)
	{
		file_name = get_filename(file_path);
		file_size = open_fstream(ifs, file_path);
		if (!file_size)
		{
			return;
			//throw std::runtime_error("File size is zero");
		}
	}
	std::istream& is = use_stdin ? std::cin : ifs;

	unsigned dots_size = 200000;
	t_progress_indicator dots(VERBOSE, dots_size);
	dots.use_timer();

	unsigned cnt_line = 0;


	//
	//	read data
	//
	try
	{
		std::string line;
		while (getline(is, line, line_separator))
		{
			++cnt_line;
			++dots;
			callback(is, cnt_line, line);
			// check every ten dots 
			if (file_size && dots.value() % (dots_size * 10) == 0)
			{
				std::istream::pos_type file_size_so_far = is.tellg();
				unsigned dots_needed = unsigned(dots.value() * 1.0 *
							file_size / file_size_so_far);
				dots_needed += dots_size;
				dots.set_limit(dots_needed);
			}
		}

	}
	catch (std::runtime_error& e)
	{
		throw std::runtime_error("Line #" + ultoa(cnt_line) + 
												" is not in the correct format: " + 
								 std::string(e.what()));
	}
}


#endif // READ_FILE_LINES_H
